package se.lcsmerge.view;

import javax.swing.SwingUtilities;

import javax.swing.DefaultListCellRenderer;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JViewport;

import java.awt.Component;
import java.awt.FileDialog;
import java.awt.Frame;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Color;
import java.io.FileNotFoundException;
import java.util.Vector;

import se.lcsmerge.util.Edit;
import se.lcsmerge.util.FileIO;
import se.lcsmerge.util.LCSCompare;
import se.lcsmerge.data.FileDataDTO;
import javax.swing.JTextArea;
/**
 * 
 * @author caucse06 SE Team
 *
 */
public class MainFrame extends JFrame {
	
	private Vector<FileDataDTO> leftFileVec;  
	private Vector<FileDataDTO> rightFileVec;  


	private String leftFileLocation;
	private String rightFileLocation;
	
	private static final long serialVersionUID = 1L;
	private JPanel jPanel = null;
	private JButton Compare = null;
	private JList leftList = null;
	private JList rightList = null;
	private JButton copyToRight = null;
	private JButton copyToLeft = null;
	private JButton leftOpen = null;
	private JButton leftSave = null;
	private JButton leftEdit = null;
	private JButton rightOpen = null;
	private JButton rightSave = null;
	private JButton rightEdit = null;
	private JTextField leftFileAddress = null;
	private JTextField rightFileAddress = null;
	private JTextArea leftTextArea = null;
	private JTextArea rightTextArea = null;
	private JScrollPane jScrollPane_L = null;
	private JScrollPane jScrollPane_R = null;
	private JScrollPane jScrollPane_L2 = null;
	private JScrollPane jScrollPane_R2 = null;
	private boolean compareToken = false;
	private boolean leftEditToken = false;
	private boolean rightEditToken = false;
	private JViewport viewPort;
	private Edit edit;  
	private LCSCompare lcs;  
	private FileIO io;  
	
	
	public Edit getEdit() {
		return edit;
	}

	public void setEdit(Edit edit) {
		this.edit = edit;
	}
	
	public void setLCSCompare(LCSCompare lcs) {
		this.lcs = lcs;
	}
	
	public void setFileIO(FileIO io) {
		this.io = io;
	}
	
	public Vector<FileDataDTO> getLeftFileVec() {
		return leftFileVec;
	}

	public void setLeftFileVec(Vector<FileDataDTO> leftFileVec) {
		this.leftFileVec = leftFileVec;
	}

	public Vector<FileDataDTO> getRightFileVec() {
		return rightFileVec;
	}

	public void setRightFileVec(Vector<FileDataDTO> rightFileVec) {
		this.rightFileVec = rightFileVec;
	}

	/**
	 * This method initializes jPanel	
	 * 	
	 * @return javax.swing.JPanel	
	 */
	public JPanel getPanel() {
		if (jPanel == null) {
			jPanel = new JPanel();
			jPanel.setLayout(null);
			jPanel.add(getLeftOpen(), null);
			jPanel.add(getLeftSave(), null);
			jPanel.add(getLeftEdit(), null);
			jPanel.add(getRightOpen(), null);
			jPanel.add(getRightSave(), null);
			jPanel.add(getRightEdit(), null);
			jPanel.add(getCompare(), null);
			jPanel.add(getCopyToRight(), null);
			jPanel.add(getCopyToLeft(), null);
			jPanel.add(getLeftFileAddress(), null);
			jPanel.add(getRightFileAddress(), null);
			jPanel.add(getJScrollPane_L(), null);
			jPanel.add(getJScrollPane_R(), null);
			
		}
		return jPanel;
	}

	/**
	 * This method initializes jScrollPane1	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JList getRightList() {
		if (rightList == null) {
			rightList = new JList();
			rightList.setBounds(new Rectangle(440, 115, 400, 500));
			rightList.setBackground(Color.white);
			rightList.setFixedCellHeight(15);

		} 
		return rightList;
	}


	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JList getLeftList() {
		if (leftList == null) {
			leftList = new JList();
			leftList.setBounds(new Rectangle(10, 115, 400, 500));
			leftList.setBackground(Color.white);
			leftList.setFixedCellHeight(15);
			
		}
		return leftList;
	}
	/**
	 * This method initializes jButton3	
	 * 	
	 * @return javax.swing.JButton	
	 */
	public JButton getLeftOpen() {
		if (leftOpen == null) {
			leftOpen = new JButton();
			leftOpen.setBounds(new Rectangle(10, 50, 70, 30));
			leftOpen.setText("open");
			leftOpen.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Frame fb = new Frame("FILE OPEN");
					FileDialog fileOpen = new FileDialog(fb, "File Open", FileDialog.LOAD);
					fileOpen.setDirectory(".\\testResources");
					fileOpen.setVisible(true);

					if(fileOpen.getFile()== null){						
						return;
					}
					
					leftFileLocation = fileOpen.getDirectory() + fileOpen.getFile();
					leftFileAddress.setText(leftFileLocation);
										
					leftFileVec = new Vector<FileDataDTO>();
					
					compareToken = false;
					if(leftEditToken==true){
						leftEdit.setText("edit");
						leftEditToken = false;
					}
					
					try {
						leftFileVec = io.readPerLine(leftFileLocation);

						leftList.setCellRenderer(new initialCellRenderer());
						setLeftFile(leftFileVec);
						
					} catch (FileNotFoundException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}			
				
				}
			});
		}
		return leftOpen;
	}
	
	public JButton getRightOpen() {
		if (rightOpen == null) {
			rightOpen = new JButton();
			rightOpen.setBounds(new Rectangle(440, 50, 70, 30));
			rightOpen.setText("open");
			rightOpen.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					Frame fb = new Frame("FILE OPEN");
					FileDialog fileOpen = new FileDialog(fb, "File Open", FileDialog.LOAD);
					fileOpen.setDirectory(".\\testResources");
					fileOpen.setVisible(true);

					if(fileOpen.getFile()== null){						
						return;
					}
					rightFileLocation = fileOpen.getDirectory() + fileOpen.getFile();
					rightFileAddress.setText(rightFileLocation);
					
					
					rightFileVec = new Vector<FileDataDTO>();
					
					compareToken = false;
					
					if(leftEditToken==true){
						leftEdit.setText("edit");
						leftEditToken = false;
					}
					
					try {
						rightFileVec = io.readPerLine(rightFileLocation);

						rightList.setCellRenderer(new initialCellRenderer());				
						setRightFile(rightFileVec);
						
					} catch (FileNotFoundException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}			
				
				}
			});
			
			
			
		}
		return rightOpen;
	}

	public JButton getLeftSave() {
		if (leftSave == null) {
			leftSave = new JButton();
			leftSave.setBounds(new Rectangle(104, 50, 70, 30));
			leftSave.setText("save");
			leftSave.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
						
					compareToken = false;
					if(leftEditToken==true){
						leftEditToken = false;
						leftEdit.setText("edit");
					}
					
					if(jPanel.isAncestorOf(getJScrollPane_L())){
						try {
							io.writePerLine(leftFileLocation, leftFileVec);
						} catch (FileNotFoundException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
							JOptionPane.showMessageDialog(null, "File can not found");
						}

					}else{
						jPanel.remove(getJScrollPane_L2());
						jPanel.add(getJScrollPane_L(), null);
						try {
							leftFileVec = io.writePerLine(leftFileLocation, getLeftTextArea().getText());
						} catch (FileNotFoundException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
							JOptionPane.showMessageDialog(null, "File can not found");
						}
						
						leftList.setCellRenderer(new initialCellRenderer());		
					}
					setLeftFile(leftFileVec);
					repaint();
				}
			});
		}
		return leftSave;
	}

	public JButton getRightSave() {
		if (rightSave == null) {
			rightSave = new JButton();
			rightSave.setBounds(new Rectangle(540, 50, 70, 30));
			rightSave.setText("save");
			rightSave.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					
					compareToken = false;
					if(rightEditToken==true){
						rightEditToken = false;
						rightEdit.setText("edit");
					}
					
					if(jPanel.isAncestorOf(getJScrollPane_R())){
						try {
							io.writePerLine(rightFileLocation, rightFileVec);
						} catch (FileNotFoundException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
							JOptionPane.showMessageDialog(null, "File can not found");
						}

					}else{
						jPanel.remove(getJScrollPane_R2());
						jPanel.add(getJScrollPane_R(), null);
						try {
							rightFileVec = io.writePerLine(rightFileLocation, getRightTextArea().getText());
						} catch (FileNotFoundException e1) {
							// TODO Auto-generated catch block
							e1.printStackTrace();
							JOptionPane.showMessageDialog(null, "File can not found");
						}

						rightList.setCellRenderer(new initialCellRenderer());		
					}
									
					setRightFile(rightFileVec);
					repaint();
				}
			});
		}
		return rightSave;
	}

	
	public JButton getLeftEdit() {
		if (leftEdit == null) {
			leftEdit = new JButton();
			leftEdit.setBounds(new Rectangle(210, 50, 70, 30));
			leftEdit.setText("edit");
			leftEdit.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(leftEditToken==false){
						leftEdit.setText("X");
						leftEditToken = true;
						jPanel.add(getJScrollPane_L2(), null);
						jPanel.remove(getJScrollPane_L());
						setLeftTextArea(leftFileVec);
					}else{
						leftEdit.setText("edit");
						leftEditToken = false;
						jPanel.remove(getJScrollPane_L2());
						jPanel.add(getJScrollPane_L(), null);
					}
					
					repaint();
				}
			});
		}
		return leftEdit;
	}

	public JButton getRightEdit() {
		if (rightEdit == null) {
			rightEdit = new JButton();
			rightEdit.setBounds(new Rectangle(640, 50, 70, 30));
			rightEdit.setText("edit");
			rightEdit.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(rightEditToken==false){
						rightEdit.setText("X");
						rightEditToken = true;
						jPanel.add(getJScrollPane_R2(), null);
						jPanel.remove(getJScrollPane_R());
						setRightTextArea(rightFileVec);
						repaint();
					}else{
						rightEdit.setText("edit");
						rightEditToken = false;
						jPanel.remove(getJScrollPane_R2());
						jPanel.add(getJScrollPane_R(), null);
					}
					repaint();
				}
			});
		}
		return rightEdit;
	}

	private JTextField getLeftFileAddress() {
		if (leftFileAddress == null) {
			leftFileAddress = new JTextField();
			leftFileAddress.setBounds(new Rectangle(10, 86, 400, 25));
			leftFileAddress.setEditable(false);
		}
		return leftFileAddress;
	}

	private JTextField getRightFileAddress() {
		if (rightFileAddress == null) {
			rightFileAddress = new JTextField();
			rightFileAddress.setBounds(new Rectangle(440, 86, 400, 25));
			rightFileAddress.setEditable(false);
		}
		return rightFileAddress;
	}


	/**
	 * This method initializes jTextArea	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getLeftTextArea() {
		if (leftTextArea == null) {
			leftTextArea = new JTextArea();
			leftTextArea.setBounds(new Rectangle(10, 115, 400, 500));
			leftTextArea.setEditable(true);
			leftTextArea.setCaretPosition(0);
			leftTextArea.enable();
		}
		return leftTextArea;
	}

	/**
	 * This method initializes rightTextArea	
	 * 	
	 * @return javax.swing.JTextArea	
	 */
	private JTextArea getRightTextArea() {
		if (rightTextArea == null) {
			rightTextArea = new JTextArea();
			rightTextArea.setBounds(new Rectangle(440, 115, 400, 500));
			rightTextArea.setCaretPosition(0);
			rightTextArea.setEditable(true);
			rightTextArea.enable();
		}
		return rightTextArea;
	}

	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane_L() {
		if (jScrollPane_L == null) {
			jScrollPane_L = new JScrollPane(getLeftList());
			jScrollPane_L.setBounds(new Rectangle(10, 115, 400, 500));
			jScrollPane_L.setVisible(true);
		}
		return jScrollPane_L;
	}

	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane_R() {
		if (jScrollPane_R == null) {
			jScrollPane_R = new JScrollPane(getRightList());
			jScrollPane_R.setBounds(new Rectangle(440, 115, 400, 500));
			jScrollPane_R.setVisible(true);
		}
		return jScrollPane_R;
	}
	
	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane_L2() {
		if (jScrollPane_L2 == null) {
			jScrollPane_L2 = new JScrollPane(getLeftTextArea());
			jScrollPane_L2.setBounds(new Rectangle(10, 115, 400, 500));
			jScrollPane_L2.setVisible(true);
			viewPort = jScrollPane_L2.getViewport();
			viewPort.add(getLeftTextArea());
			viewPort.setViewPosition(new Point(0,0));
		}
		return jScrollPane_L2;
	}
	
	/**
	 * This method initializes jScrollPane	
	 * 	
	 * @return javax.swing.JScrollPane	
	 */
	private JScrollPane getJScrollPane_R2() {
		if (jScrollPane_R2 == null) {
			jScrollPane_R2 = new JScrollPane(getRightTextArea());
			jScrollPane_R2.setBounds(new Rectangle(440, 115, 400, 500));
			jScrollPane_R2.setVisible(true);
			viewPort = jScrollPane_R2.getViewport();
			viewPort.add(getRightTextArea());
			viewPort.setViewPosition(new Point(0,0));
		}



		return jScrollPane_R2;
	}
	
	public void runMainFrame() {
		// TODO Auto-generated method stub
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				MainFrame thisClass = new MainFrame();
				thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				
			}
		});
	}

	public JButton getCompare() {
		if (Compare == null) {
			Compare = new JButton();
			Compare.setBounds(new Rectangle(355, 625, 120, 30));
			Compare.setText("compare");
			Compare.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					
					Vector<String> tempLeft = new Vector<String>();
					Vector<String> tempRight = new Vector<String>();
					
					if(compareToken==false){
						compareToken = true;
					
						lcs.init(leftFileVec, rightFileVec);
					
						leftFileVec = lcs.getLeft();
						rightFileVec = lcs.getRight();
					}
					
					for(int i=0; i <leftFileVec.size(); i++){
						tempLeft.add(leftFileVec.get(i).getString()); 
					}			
					
					for(int i=0; i <rightFileVec.size(); i++){
						tempRight.add(rightFileVec.get(i).getString()); 
					}			
								
					
					leftList.setListData(tempLeft);
					leftList.setCellRenderer(new leftListCellRenderer());
					rightList.setListData(tempRight);
					rightList.setCellRenderer(new rightListCellRenderer());
									
				
				}
			});
		}
		return Compare;
	}

	public JButton getCopyToRight() {
		if (copyToRight == null) {
			copyToRight = new JButton();
			copyToRight.setText("copy to right");
			copyToRight.setBounds(new Rectangle(200, 625, 120, 30));
			copyToRight.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					
					if(compareToken == true){
						rightFileVec = runCopyToRight(leftFileVec, rightFileVec, leftList.getSelectedIndex());
						setRightFile(rightFileVec);
					}else
						JOptionPane.showMessageDialog(null, "Please compare first");
					
				}
			});
		}
		return copyToRight;
	}
////////////////////////////////////////////////
	public JButton getCopyToLeft() {
		if (copyToLeft == null) {
			copyToLeft = new JButton();
			copyToLeft.setText("copy to left");
			copyToLeft.setBounds(new Rectangle(510, 625, 120, 30));
			copyToLeft.addActionListener(new java.awt.event.ActionListener() {
				public void actionPerformed(java.awt.event.ActionEvent e) {
					if(compareToken==true){
						leftFileVec = runCopyToLeft(leftFileVec, rightFileVec, rightList.getSelectedIndex());
						setLeftFile(leftFileVec);
					}else 
						JOptionPane.showMessageDialog(null, "Please compare first");
					
				}
			});
		}
		return copyToLeft;
	}

	public MainFrame() {
		super();
		initialize();
	}

	private void initialize() {
		this.setSize(860, 700);
		this.setContentPane(getPanel());
		this.setTitle("lcsMerge");
	}
	
	public Vector<FileDataDTO> runCopyToRight(Vector<FileDataDTO> left,
			Vector<FileDataDTO> right, int index) {
		// TODO Auto-generated method stub
						
		return edit.copyToRight(left, right, index);

	}

	public Vector<FileDataDTO> runCopyToLeft(Vector<FileDataDTO> left,
			Vector<FileDataDTO> right, int index) {
		// TODO Auto-generated method stub

		return edit.copyToLeft(left, right, index);

	}
	
	

	class leftListCellRenderer extends DefaultListCellRenderer {
		
		private static final long serialVersionUID = 1L;

		public Component getListCellRendererComponent(JList list, Object value,  
				int index, boolean isSelected, boolean cellHasFocus) {
			// Return a component that has been configured to display the specified value
			
			JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
			// Call it's super method to return JLabel which handled by CellRenderer.
			
			try {            // Compare the elements of JList				
				
				if (leftFileVec.get(index).getColor() == 0) {
					label.setBackground(Color.ORANGE); // When user want to find different line
				}
				else if(leftFileVec.get(index).getColor() == 1) {
					label.setBackground(Color.GRAY); // When right file has blank, setting background color gray.  
				}else{
					label.setBackground(Color.WHITE);
				}
			
			} catch(ArrayIndexOutOfBoundsException ai) {
				setBackground(Color.BLUE); // Set JList elements as blue color if the compared result isn't equal
				} catch(StringIndexOutOfBoundsException si) {
					System.out.println("error!");
					}
				if(isSelected) {
					// if the elements are selected,
					setBackground(Color.PINK);         // coloring as pink.
					}
				return label;
				}
		
	}
	
	class rightListCellRenderer extends DefaultListCellRenderer {
		
		private static final long serialVersionUID = 1L;

		public Component getListCellRendererComponent(JList list, Object value,  
				int index, boolean isSelected, boolean cellHasFocus) {
			// Return a component that has been configured to display the specified value
			
			JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
			// Call it's super method to return JLabel which handled by CellRenderer.
			
			try {            // Compare the elements of JList				
				
				if (rightFileVec.get(index).getColor() == 0) {
					label.setBackground(Color.ORANGE); // When user want to find different line
				}
				else if(rightFileVec.get(index).getColor() == 1) {
					label.setBackground(Color.GRAY); // When right file has blank, setting background color gray.  
				}else{
					label.setBackground(Color.WHITE);
				}
			
			} catch(ArrayIndexOutOfBoundsException ai) {
				setBackground(Color.BLUE); // Set JList elements as blue color if the compared result isn't equal
				} catch(StringIndexOutOfBoundsException si) {
					System.out.println("error!");
					}
				if(isSelected) {
					// if the elements are selected,
					setBackground(Color.PINK);         // coloring as pink.
					}
				return label;
				}
		
	}

	class initialCellRenderer extends DefaultListCellRenderer {
		
		private static final long serialVersionUID = 1L;

		public Component getListCellRendererComponent(JList list, Object value,  
				int index, boolean isSelected, boolean cellHasFocus) {
			// Return a component that has been configured to display the specified value
			
			JLabel label = (JLabel)super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
			// Call it's super method to return JLabel which handled by CellRenderer.
			
			try {            // Compare the elements of JList				
				label.setBackground(Color.WHITE);
							
			} catch(ArrayIndexOutOfBoundsException ai) {
				setBackground(Color.BLUE); // Set JList elements as blue color if the compared result isn't equal
				} catch(StringIndexOutOfBoundsException si) {
					System.out.println("error!");
					}
				if(isSelected) {
					// if the elements are selected,
					setBackground(Color.PINK);         // coloring as pink.
					}
				return label;
				}
		
	}
	
	public void setLeftFile(Vector<FileDataDTO> data){
		Vector<String> tempV = new Vector<String>();
		
		for(int i=0; i <data.size(); i++){
			tempV.add(data.get(i).getString()); 
		}
		leftList.setListData(tempV);
	
	}
	
	public void setRightFile(Vector<FileDataDTO> data){
		Vector<String> tempV = new Vector<String>();
		
		for(int i=0; i <data.size(); i++){
			tempV.add(data.get(i).getString()); 
		}
		rightList.setListData(tempV);
	}
	
	public void setLeftTextArea(Vector<FileDataDTO> data){
		StringBuffer sb = new StringBuffer();
		for(int i=0; i <data.size(); i++){
			sb.append(data.get(i).getString());
			if(i!=data.size()) sb.append("\n");
		}
		leftTextArea.setText(sb.toString());
	}
	
	public void setRightTextArea(Vector<FileDataDTO> data){
		StringBuffer sb = new StringBuffer();
		for(int i=0; i <data.size(); i++){
			sb.append(data.get(i).getString());
			if(i!=data.size()) sb.append("\n");
		}
		rightTextArea.setText(sb.toString());
	}
	
	
	
}  //  @jve:decl-index=0:visual-constraint="4,2"
